package com.wiloon.javax.tmp.itext;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.parser.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ITextx0 {

    public static void main(String[] args) throws IOException, DocumentException {
        PdfReader reader = new PdfReader("/home/u/tmp/xx.pdf");

        Map<String, Annotation> unHandledReply = new HashMap();
        Map<String, Annotation> annotMap = new HashMap();
        List<Annotation> list = new ArrayList<>();


        for (int pageIndex = 1; pageIndex <= reader.getNumberOfPages(); pageIndex++) {
//            PdfArray highlight = reader.getPageN(i).getAsArray(PdfName.HIGHLIGHT);
//            if (highlight != null)
//                System.out.println("highlight size:" + highlight.size());

            PdfArray annotList = reader.getPageN(pageIndex).getAsArray(PdfName.ANNOTS);


            if (annotList == null) continue;

            System.out.println("page:" + pageIndex + ", annot size:" + annotList.size());


            for (int annotIndex = 0; annotIndex < annotList.size(); annotIndex++) {
                PdfDictionary annot = annotList.getAsDict(annotIndex);
                // annot.getAsIndirectObject(0);

                PdfObject refObj = (PdfObject) annot;
                PdfDictionary an = (PdfDictionary) PdfReader.getPdfObject(refObj);
                PdfString text = annot.getAsString(PdfName.CONTENTS);

                if (text == null) continue;
                System.out.println(text);

                PdfString time = annot.getAsString(PdfName.CREATIONDATE);
                PdfString name = annot.getAsString(PdfName.T);

                PdfArray rectangle = (PdfArray) annot.get(PdfName.RECT);
                String content = getTextFromRectangle(rectangle, reader, pageIndex);
                PdfDictionary pArray = annot.getAsDict(PdfName.P);
                String p = pArray.get(PdfName.CONTENTS).toString();

                PdfString nm = annot.getAsString(PdfName.NM);

                Annotation annotation = new Annotation();

                annotation.setUser(name.toString());
                annotation.setComment(text.toString());
                annotation.setTime(time.toString());
                annotation.setId(nm.toString());
                annotation.setPage(pageIndex);
                annotation.setContent(content);

                PdfDictionary irtDict = annot.getAsDict(PdfName.IRT);
                if (irtDict != null) {
                    String nmTmp = irtDict.getAsString(PdfName.NM).toString();
                    Annotation parent = annotMap.get(nmTmp);
                    if (parent == null) {
                        System.out.println("can not find annot by nm:" + nmTmp + ", comments:" + annotation.getComment() + ", page:" + annotation.getPage());
                        unHandledReply.put(nmTmp, annotation);
                    } else {
                        parent.addReply(annotation);
                    }

                } else {
                    if (unHandledReply.get(annotation.getId()) != null) {
                        annotation.addReply(unHandledReply.get(annotation.getId()));
                        System.out.println("recover unhandled annotation:" + annotation.getId());
                    }
                    annotMap.put(annotation.getId(), annotation);
                    list.add(annotation);

                }

            }
        }

        Workbook wb = new XSSFWorkbook();
        CreationHelper createHelper = wb.getCreationHelper();
        Sheet sheet = wb.createSheet("new sheet");

        int index = 1;
        for (int rowIndex = 0; rowIndex < list.size(); rowIndex++) {
            Annotation annotTmp = list.get(rowIndex);
            Row row = sheet.createRow(rowIndex);

            row.createCell(0).setCellValue(index++);
            row.createCell(1).setCellValue(
                    createHelper.createRichTextString(list.get(rowIndex).getContent()));
            row.createCell(2).setCellValue(createHelper.createRichTextString(annotTmp.getComment()));
            List<Annotation> replys = annotTmp.getReplys();
            if (replys == null || replys.size() == 0) {
                row.createCell(3).setCellValue("reply not found");
            } else {
                row.createCell(3).setCellValue(createHelper.createRichTextString(replys.get(0).getComment()));
            }

            row.createCell(4).setCellValue("page:" + annotTmp.getPage());
            row.createCell(5).setCellValue("Id:" + annotTmp.getId());
        }

        FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
        wb.write(fileOut);
        fileOut.close();

        System.out.println("end");
    }


    public static String getTextFromRectangle(PdfArray rectangle,
                                              PdfReader reader, int pageNumber) throws IOException {

        if (rectangle == null) {
            return null;
        }

        // Get the retangle coodinates
        float llx = rectangle.getAsNumber(0).floatValue();
        float lly = rectangle.getAsNumber(1).floatValue();
        float urx = rectangle.getAsNumber(2).floatValue();
        float ury = rectangle.getAsNumber(3).floatValue();

        Rectangle rect = new Rectangle(llx, lly, urx, ury);
        RenderFilter filter = new RegionTextRenderFilter(rect);
        TextExtractionStrategy strategy =
                new FilteredTextRenderListener(
                        new LocationTextExtractionStrategy(), filter);

        return PdfTextExtractor.getTextFromPage(reader, pageNumber, strategy);
    }

}
